using System;
using System.Collections.Generic;
using System.Security.Permissions;
using System.Text;

namespace Oracle.ManagedDataAccess.Client
{
	internal static class OraclePerfCounterCollection
	{
		private static readonly Dictionary<string, OraclePerfCounter>[] m_countersList;

		private static readonly string[] m_counterNames;

		private static object syncLock;

		[SecurityPermission(SecurityAction.Assert, UnmanagedCode = true)]
		static OraclePerfCounterCollection()
		{
			m_countersList = new Dictionary<string, OraclePerfCounter>[12];
			m_counterNames = new string[12];
			syncLock = new object();
			try
			{
				HookToDomainUnloadOrProcessExitEvent();
				InitializePerformanceCounters();
			}
			catch (Exception)
			{
			}
		}

		public static void Initialize()
		{
		}

		internal static OraclePerfCounter Increment(OraclePerfParams.CounterIndex iCounter, string poolName, string dbInstanceName)
		{
			OraclePerfCounter value = null;
			if (m_countersList[(int)iCounter] != null)
			{
				string text = CreateInstanceName(OraclePerfParams.m_appDomainPfcInstanceName, poolName, dbInstanceName);
				if (!m_countersList[(int)iCounter].TryGetValue(text, out value))
				{
					value = CreatePerformanceCounters(iCounter, text);
				}
				value.Increment();
			}
			return value;
		}

		private static string CreateInstanceName(string appDomain, string poolName, string dbInstanceName)
		{
			poolName = ConstructFieldName(poolName, 70);
			dbInstanceName = ConstructFieldName(dbInstanceName, 16);
			return new StringBuilder().Append(appDomain).Append(poolName).Append(dbInstanceName)
				.ToString();
		}

		private static string ConstructFieldName(string fieldName, int lengthLimit)
		{
			if (fieldName != null)
			{
				if (fieldName.Length > lengthLimit)
				{
					fieldName = fieldName.Substring(0, lengthLimit - 3) + "...";
				}
				fieldName = new StringBuilder().Append("[").Append(fieldName).Append("]")
					.ToString();
			}
			return fieldName;
		}

		internal static OraclePerfCounter IncrementBy(OraclePerfParams.CounterIndex iCounter, int value, string poolName, string dbInstanceName)
		{
			OraclePerfCounter value2 = null;
			if (m_countersList[(int)iCounter] != null)
			{
				string text = CreateInstanceName(OraclePerfParams.m_appDomainPfcInstanceName, poolName, dbInstanceName);
				if (!m_countersList[(int)iCounter].TryGetValue(text, out value2))
				{
					value2 = CreatePerformanceCounters(iCounter, text);
				}
				value2.IncrementBy(value);
			}
			return value2;
		}

		internal static OraclePerfCounter Decrement(OraclePerfParams.CounterIndex iCounter, string poolName, string dbInstanceName)
		{
			OraclePerfCounter value = null;
			if (m_countersList[(int)iCounter] != null)
			{
				string text = CreateInstanceName(OraclePerfParams.m_appDomainPfcInstanceName, poolName, dbInstanceName);
				if (!m_countersList[(int)iCounter].TryGetValue(text, out value))
				{
					value = CreatePerformanceCounters(iCounter, text);
				}
				value?.Decrement();
			}
			return value;
		}

		private static OraclePerfCounter CreatePerformanceCounters(OraclePerfParams.CounterIndex iCount, string pfcInstanceName)
		{
			Dictionary<string, OraclePerfCounter> dictionary = m_countersList[(int)iCount];
			string[] array = new string[3];
			int num = pfcInstanceName.IndexOf(']');
			if (num != -1)
			{
				array[0] = pfcInstanceName.Substring(0, num + 1);
				num = pfcInstanceName.IndexOf(']', num + 1);
				if (num != -1)
				{
					array[1] = pfcInstanceName.Substring(0, num + 1);
				}
			}
			array[2] = pfcInstanceName;
			OraclePerfCounter oraclePerfCounter = null;
			string[] array2 = array;
			foreach (string text in array2)
			{
				if (string.IsNullOrEmpty(text))
				{
					break;
				}
				if (!dictionary.TryGetValue(text, out var value))
				{
					lock (syncLock)
					{
						if (!dictionary.TryGetValue(text, out value))
						{
							value = new OraclePerfCounter(m_counterNames[(int)iCount], text);
							value.m_higherLevelCounter = oraclePerfCounter;
							dictionary.Add(text, value);
						}
					}
				}
				oraclePerfCounter = value;
			}
			return oraclePerfCounter;
		}

		private static void Dispose()
		{
			for (int i = 0; i < 12; i++)
			{
				foreach (OraclePerfCounter value in m_countersList[i].Values)
				{
					if (value != null)
					{
						try
						{
							value.Dispose();
						}
						catch (Exception)
						{
						}
					}
				}
				m_countersList[i].Clear();
				m_countersList[i] = null;
			}
		}

		private static void HookToDomainUnloadOrProcessExitEvent()
		{
			if (AppDomain.CurrentDomain.IsDefaultAppDomain())
			{
				AppDomain.CurrentDomain.ProcessExit += new EventHandler(DomainUnloadOrProcessExit);
			}
			else
			{
				AppDomain.CurrentDomain.DomainUnload += new EventHandler(DomainUnloadOrProcessExit);
			}
		}

		private static void DomainUnloadOrProcessExit(object sender, EventArgs e)
		{
			Dispose();
		}

		private static void InitializePerformanceCounters()
		{
			if (!string.IsNullOrEmpty("ODP.NET, Core Driver") && !string.IsNullOrEmpty(OraclePerfParams.m_appDomainPfcInstanceName))
			{
				string appDomainPfcInstanceName = OraclePerfParams.m_appDomainPfcInstanceName;
				m_countersList[0] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[0].Add(appDomainPfcInstanceName, new OraclePerfCounter("HardConnectsPerSecond"));
				m_counterNames[0] = "HardConnectsPerSecond";
				m_countersList[1] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[1].Add(appDomainPfcInstanceName, new OraclePerfCounter("HardDisconnectsPerSecond"));
				m_counterNames[1] = "HardDisconnectsPerSecond";
				m_countersList[2] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[2].Add(appDomainPfcInstanceName, new OraclePerfCounter("SoftConnectsPerSecond"));
				m_counterNames[2] = "SoftConnectsPerSecond";
				m_countersList[3] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[3].Add(appDomainPfcInstanceName, new OraclePerfCounter("SoftDisconnectsPerSecond"));
				m_counterNames[3] = "SoftDisconnectsPerSecond";
				m_countersList[4] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[4].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfActiveConnectionPools"));
				m_counterNames[4] = "NumberOfActiveConnectionPools";
				m_countersList[5] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[5].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfActiveConnections"));
				m_counterNames[5] = "NumberOfActiveConnections";
				m_countersList[6] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[6].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfFreeConnections"));
				m_counterNames[6] = "NumberOfFreeConnections";
				m_countersList[7] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[7].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfInactiveConnectionPools"));
				m_counterNames[7] = "NumberOfInactiveConnectionPools";
				m_countersList[8] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[8].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfNonPooledConnections"));
				m_counterNames[8] = "NumberOfNonPooledConnections";
				m_countersList[9] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[9].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfPooledConnections"));
				m_counterNames[9] = "NumberOfPooledConnections";
				m_countersList[10] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[10].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfReclaimedConnections"));
				m_counterNames[10] = "NumberOfReclaimedConnections";
				m_countersList[11] = new Dictionary<string, OraclePerfCounter>();
				m_countersList[11].Add(appDomainPfcInstanceName, new OraclePerfCounter("NumberOfStasisConnections"));
				m_counterNames[11] = "NumberOfStasisConnections";
			}
		}
	}
}
